package com.snapp.util.factory;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Vector;

import org.apache.log4j.Logger;

import com.snapp.util.Bean;
import com.snapp.util.object.model.ObjectModel;
import com.snapp.util.service.db.DBService;
import com.snapp.util.service.model.ServiceModel;

public class Factory implements Serializable{
	private static final long serialVersionUID = -5925533734719073489L;
	
	private static Logger logger = Logger.getLogger(Factory.class);

	// hide constructor
	private Factory(){}
	
	public static synchronized void registerObject(ObjectModel model) {
		Cache.INSTANCE.objectRegistry.add(model);
	}

	public static synchronized void registerService(ServiceModel model) {
		Cache.INSTANCE.serviceRegistry.add(model);
	}
	
	// add to index
	public static synchronized void addObjectIndex(String globalId, ObjectModel obj) {
		Cache.INSTANCE.objectIndex.put(globalId, obj);
	}
	public static synchronized ObjectModel getObject(String globalId) {
		return Cache.INSTANCE.objectIndex.get(globalId);
	}

	/**
	 * Load the static objects registry
	 */
	public static synchronized void reset() {
		
		Cache.INSTANCE.objectIndex = new HashMap<String, ObjectModel>();
		try {

  			for (ObjectModel model : Cache.INSTANCE.objectRegistry) {
				logger.info("Found class:  "+model.getClass().getName());
		
				String sql = "select o.globalid, o.globalname, o.readonly, oe.*" +
						" from "+Cache.INSTANCE.OBJECT_TABLE+" o, "+model.getTableName()+" oe " +
						" where oe.object = o.id and status = 1;";
 				
				DBService dbs = new DBService();
				
				Vector<Bean> beans = dbs.listBeans(Cache.INSTANCE.DEFAULT_JNDI_NAME, sql);
				
				for (Bean bean : beans) {
					Bean nBean = bean.getCopy();
					
					ObjectModel nxt = model.getClass().newInstance();
					
					logger.info("creating instance: " + nxt.getClass().getName() + ":  "+nBean.getPropertyString("globalid"));
					
					nxt.fromBean(nBean);
					
					nBean.setProperty("propertyNames", nxt.getPropertyNames(), nxt.getPropertyNames().toString());
					
					addObjectIndex(nBean.getPropertyString("globalid"), nxt);
				}
				
			}

		} catch(Exception e) {
			logger.error("Error resetting factory!",e);
		}

	}

	private enum Cache {
		INSTANCE;
		
		private final String DEFAULT_JNDI_NAME = "java:/snapp";
		private final String OBJECT_TABLE = "Objects";

		public Vector<ObjectModel> objectRegistry = new Vector<ObjectModel>();

		public Vector<ServiceModel> serviceRegistry = new Vector<ServiceModel>();

		/**
		 * Indexed contents of the object factory
		 */
		public HashMap<String,ObjectModel> objectIndex = null;
		


	}
	

}
